summaryrefslogtreecommitdiff
path: root/app/[lng]/engineering/(engineering)/report/page.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'app/[lng]/engineering/(engineering)/report/page.tsx')
-rw-r--r--app/[lng]/engineering/(engineering)/report/page.tsx154
1 files changed, 118 insertions, 36 deletions
diff --git a/app/[lng]/engineering/(engineering)/report/page.tsx b/app/[lng]/engineering/(engineering)/report/page.tsx
index 3efaa7c3..eb932e0f 100644
--- a/app/[lng]/engineering/(engineering)/report/page.tsx
+++ b/app/[lng]/engineering/(engineering)/report/page.tsx
@@ -1,47 +1,129 @@
-import * as React from "react"
-import { Skeleton } from "@/components/ui/skeleton"
-import { DataTableSkeleton } from "@/components/data-table/data-table-skeleton"
-import { Shell } from "@/components/shell"
+// app/procurement/dashboard/page.tsx
+import * as React from "react";
+import { Skeleton } from "@/components/ui/skeleton";
+import { Shell } from "@/components/shell";
+import { ErrorBoundary } from "@/components/error-boundary";
+import { getDashboardData } from "@/lib/dashboard/service";
+import { DashboardClient } from "@/lib/dashboard/dashboard-client";
+// 대시보드 데이터 로딩 컴포넌트
+async function DashboardContent() {
+ try {
+ const data = await getDashboardData("engineering");
+
+ const handleRefresh = async () => {
+ "use server";
+ return await getDashboardData("engineering");
+ };
-export default async function IndexPage() {
-
+ return (
+ <DashboardClient
+ initialData={data}
+ onRefresh={handleRefresh}
+ />
+ );
+ } catch (error) {
+ console.error("Dashboard data loading error:", error);
+ throw error;
+ }
+}
+// 대시보드 로딩 스켈레톤
+function DashboardSkeleton() {
return (
- <Shell className="gap-2">
+ <div className="space-y-6">
+ {/* 헤더 스켈레톤 */}
<div className="flex items-center justify-between">
- <div>
- <h2 className="text-2xl font-bold tracking-tight">
- Dashboard
- </h2>
- <p className="text-muted-foreground">
- 각종 지표 등을 대시보드로 표현하거나 리포트를 출력할 수 있습니다.
- </p>
+ <div className="space-y-2">
+ <Skeleton className="h-8 w-48" />
+ <Skeleton className="h-4 w-72" />
+ </div>
+ <Skeleton className="h-10 w-24" />
+ </div>
+
+ {/* 요약 카드 스켈레톤 */}
+ <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
+ {[...Array(4)].map((_, i) => (
+ <div key={i} className="space-y-3 p-6 border rounded-lg">
+ <div className="flex items-center justify-between">
+ <Skeleton className="h-4 w-16" />
+ <Skeleton className="h-4 w-4" />
+ </div>
+ <Skeleton className="h-8 w-12" />
+ <Skeleton className="h-3 w-20" />
+ </div>
+ ))}
+ </div>
+
+ {/* 차트 스켈레톤 */}
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
+ {[...Array(2)].map((_, i) => (
+ <div key={i} className="space-y-4 p-6 border rounded-lg">
+ <div className="space-y-2">
+ <Skeleton className="h-6 w-32" />
+ <Skeleton className="h-4 w-48" />
+ </div>
+ <Skeleton className="h-[300px] w-full" />
+ </div>
+ ))}
+ </div>
+
+ {/* 탭 스켈레톤 */}
+ <div className="space-y-4">
+ <Skeleton className="h-10 w-64" />
+ <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
+ {[...Array(6)].map((_, i) => (
+ <div key={i} className="space-y-4 p-6 border rounded-lg">
+ <Skeleton className="h-6 w-32" />
+ <div className="space-y-3">
+ <div className="flex justify-between">
+ <Skeleton className="h-4 w-16" />
+ <Skeleton className="h-4 w-12" />
+ </div>
+ <div className="flex gap-2">
+ <Skeleton className="h-6 w-16" />
+ <Skeleton className="h-6 w-16" />
+ <Skeleton className="h-6 w-16" />
+ </div>
+ <Skeleton className="h-2 w-full" />
+ </div>
+ </div>
+ ))}
</div>
</div>
+ </div>
+ );
+}
- <React.Suspense fallback={<Skeleton className="h-7 w-52" />}>
- {/* <DateRangePicker
- triggerSize="sm"
- triggerClassName="ml-auto w-56 sm:w-60"
- align="end"
- shallow={false}
- /> */}
- </React.Suspense>
-
- <React.Suspense
- fallback={
- <DataTableSkeleton
- columnCount={6}
- searchableColumnCount={1}
- filterableColumnCount={2}
- cellWidths={["10rem", "40rem", "12rem", "12rem", "8rem", "8rem"]}
- shrinkZero
- />
- }
+// 에러 표시 컴포넌트
+function DashboardError({ error, reset }: { error: Error; reset: () => void }) {
+ return (
+ <div className="flex flex-col items-center justify-center py-12 space-y-4">
+ <div className="text-center space-y-2">
+ <h3 className="text-lg font-semibold">대시보드를 불러올 수 없습니다</h3>
+ <p className="text-muted-foreground">
+ {error.message || "알 수 없는 오류가 발생했습니다."}
+ </p>
+ </div>
+ <button
+ onClick={reset}
+ className="px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90"
>
- </React.Suspense>
+ 다시 시도
+ </button>
+ </div>
+ );
+}
+
+export default async function DashboardPage() {
+ return (
+ <Shell className="gap-6">
+ <ErrorBoundary fallback={DashboardError}>
+ <React.Suspense fallback={<DashboardSkeleton />}>
+ <DashboardContent />
+ </React.Suspense>
+ </ErrorBoundary>
</Shell>
- )
-} \ No newline at end of file
+ );
+}